﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace IndirectX
{
    public class DataStream : Stream
    {
        private long _sizeInBytes;
        private bool _canRead;
        private bool _canWrite;

        private MemoryStream _internalStream;

        public DataStream(long sizeInBytes, bool canRead, bool canWrite)
        {
            this._sizeInBytes = sizeInBytes;
            this._canRead = canRead;
            this._canWrite = canWrite;

            _internalStream = new MemoryStream(new byte[sizeInBytes], canWrite);
        }

        public override void Flush()
        {
            _internalStream.Flush();
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return _internalStream.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            _internalStream.SetLength(value);
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return _internalStream.Read(buffer, offset, count);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            _internalStream.Write(buffer, offset, count);
        }



        public override long Position
        {
            get { return _internalStream.Position; }
            set { _internalStream.Position = value; }
        }

        public void Write<T>(T value) where T: struct
        {
            int size = Marshal.SizeOf(value);
            byte[] buffer = new byte[size];
            IntPtr ptr = Marshal.AllocHGlobal(size);

            Marshal.StructureToPtr(value, ptr, true);
            Marshal.Copy(ptr, buffer, 0, size);
            Marshal.FreeHGlobal(ptr);

            this.Write(buffer, 0, size);
        }


        public override bool CanRead
        {
            get { return _canRead; }
        }

        public override bool CanSeek
        {
            get { return true; }
        }

        public override bool CanWrite
        {
            get { return _canWrite; }
        }

        public override long Length
        {
            get { return _sizeInBytes; }
        }
    }
}
